﻿#region zh-CHS 2006 - 2007 DemoSoft 团队 | en 2006 - 2007 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the G.O.S.E(Game Online Server Engine) for .NET.
//
//                 2006-2007 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Collections.Generic;
using Demo_G.O.S.E.ServerEngine.Util;
#endregion

namespace Demo_G.O.S.E.ServerEngine.World
{
    /// <summary>
    /// 一般用于SQL的回调
    /// </summary>
    public class WorldWaitExecute
    {
        #region zh-CHS 共有属性 | en Public Properties

        #region zh-CHS BaseWorld属性 | en BaseWorld Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 管理当前的世界服务
        /// </summary>
        private BaseWorld m_BaseWorld = null;
        #endregion
        /// <summary>
        /// 管理当前的世界服务
        /// </summary>
        public BaseWorld BaseWorld
        {
            get { return m_BaseWorld; }
        }

        #region zh-CHS 内部方法 | en Internal Methods
        /// <summary>
        /// 设置管理当前的世界服务
        /// </summary>
        /// <param name="baseWorld"></param>
        internal void SetBaseWorld( BaseWorld baseWorld )
        {
            m_BaseWorld = baseWorld;
        }
        #endregion

        #endregion

        #endregion

        #region zh-CHS 内部方法 | en Internal Methods

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 是否在调用Slice(...)中...(防止多线程多次调用Slice(...)函数)
        /// </summary>
        private bool m_InSliceWaitExecute = false;
        /// <summary>
        /// 是否在调用Slice(...)中...的锁
        /// </summary>
        private ReaderWriterLockSlim m_LockInSliceWaitExecute = new ReaderWriterLockSlim();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        internal void Slice()
        {
            bool bIsChange = false;

            // 检查是否已经在处理Slice(...)的调用
            if ( ReaderWriterLockSlimEx.TryEnterWriteLock( m_LockInSliceWaitExecute ) == false )
                return;
            {
                if ( m_InSliceWaitExecute == false ) // 没有锁定
                    bIsChange = m_InSliceWaitExecute = true;
            }
            ReaderWriterLockSlimEx.ExitWriteLock( m_LockInSliceWaitExecute );

            // 已经在处理Slice(...)中
            if ( bIsChange == false && m_InSliceWaitExecute )
                return;

            IWaitExecuteInfo[] waitExecuteArray = null;
            do
            {
                waitExecuteArray = null;

                ReaderWriterLockSlimEx.EnterWriteLock( m_LocksWaitExecuteQueue );
                {
                    if ( m_WaitExecuteQueue.Count > 0 )
                    {
                        waitExecuteArray = m_WaitExecuteQueue.ToArray();
                        m_WaitExecuteQueue.Clear();
                    }
                }
                ReaderWriterLockSlimEx.ExitWriteLock( m_LocksWaitExecuteQueue );

                if ( waitExecuteArray == null )
                    break;

                foreach ( IWaitExecuteInfo iWaitExecuteInfo in waitExecuteArray )
                    iWaitExecuteInfo.Execute(); 

            } while ( waitExecuteArray != null );// 可能执行的时间比较长 所以再检测一下是不是还有


            // 已经处理完Slice(...)的调用
            ReaderWriterLockSlimEx.EnterWriteLock( m_LockInSliceWaitExecute );
            {
                m_InSliceWaitExecute = false;
            }
            ReaderWriterLockSlimEx.ExitWriteLock( m_LockInSliceWaitExecute );
        }

        #endregion

        #region zh-CHS 共有方法 | en Public Methods

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 当前需要处理的集合
        /// </summary>
        private Queue<IWaitExecuteInfo> m_WaitExecuteQueue = new Queue<IWaitExecuteInfo>();
        /// <summary>
        /// 
        /// </summary>
        private ReaderWriterLockSlim m_LocksWaitExecuteQueue = new ReaderWriterLockSlim();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="waitCallBack"></param>
        public void JoinWaitExecuteQueue( IWaitExecuteInfo waitExecuteInfo )
        {
            if ( waitExecuteInfo == null )
            {
                Debug.WriteLine( "WorldWaitExecute.JoinWaitExecuteQueue(...) - waitExecuteInfo == null error!" );
                return;
            }

            ReaderWriterLockSlimEx.EnterWriteLock( m_LocksWaitExecuteQueue );
            {
                m_WaitExecuteQueue.Enqueue( waitExecuteInfo );
            }
            ReaderWriterLockSlimEx.ExitWriteLock( m_LocksWaitExecuteQueue );

            BaseWorld tempWorld = m_BaseWorld;
            if ( tempWorld != null )
                tempWorld.SetWorldSignal();
            else
                Debug.WriteLine( "WorldWaitExecute.JoinWaitExecuteQueue(...) - m_BaseWorld == null error!" );
        }

        #endregion
    }
}
#endregion